#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QWidget"
#include <QLayout>
#include "parser/yacc.tab.h"
#include <QApplication>
#include "error.h"
#include <QTextStream>
#include <QInputDialog>
#include <QDir>
#include <QFileInfo>
#include <QDateTime>
#include <QCryptographicHash>
#include <QDockWidget>
#include <QProcess>
#include <QMessageBox>
#include <QComboBox>
#include <QToolButton>
#include "other/logs.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow),superuser(SuperUser("sys")),
      username("root"),currentUser(SuperUser(username.toStdString()))
{
    ui->setupUi(this);
    // 设置窗口状态为最大化
    this->setWindowState(Qt::WindowMaximized);
    openDb = false;
    resNum = 0;
    toolBarInit();
    stackWidgetInit();
    userInit();//初始化，创建用户表以及权限表
    treeWidgetInit();//加载test里面的所有数据库以及表
    tabWidgetInit();
    dockWidgetInit();
}

MainWindow::~MainWindow()
{
    delete ui;
}
//初始化toolbar
void MainWindow::toolBarInit()
{
    // 创建圆形按钮
    QToolButton* roundButton = new QToolButton(ui->toolBar);
    roundButton->setIcon(QIcon(":/img/currentUser.png")); // 替换为你的图标路径
    roundButton->setIconSize(roundButton->sizeHint()); // 设置图标大小
    roundButton->setText(QString::fromStdString(currentUser.getUsername()));
    roundButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    QWidget* widget = new QWidget();
    QHBoxLayout *hlayout = new QHBoxLayout();
    hlayout->addStretch();
    hlayout->addWidget(roundButton);
    widget->setLayout(hlayout);
    // 将圆形按钮添加到QToolBar的末尾
    ui->toolBar->addWidget(widget);
}
//初始化stackwidget
void MainWindow::stackWidgetInit()
{
    // 创建水平布局
    QHBoxLayout *hlayout1 = new QHBoxLayout();
    hlayout1->addWidget(ui->showTable);
    hlayout1->addWidget(ui->alterTable);
    hlayout1->addWidget(ui->createTable);
    hlayout1->addWidget(ui->deleteTable);
    hlayout1->addStretch();//增加一个可伸缩空间
    hlayout1->setContentsMargins(10, 10, 10, 10);//left,top,right,bottom
    ui->showTable->setEnabled(false);
    ui->alterTable->setEnabled(false);
    ui->createTable->setEnabled(false);
    ui->deleteTable->setEnabled(false);
    ui->tableBar->setLayout(hlayout1);
    // 创建水平布局
    QHBoxLayout *hlayout2 = new QHBoxLayout();
    hlayout2->addWidget(ui->alterFind);
    hlayout2->addWidget(ui->createFind);
    hlayout2->addWidget(ui->deleteFind);
    hlayout2->addStretch();//增加一个可伸缩空间
    hlayout2->setContentsMargins(10, 10, 10, 10);//left,top,right,bottom
    ui->alterFind->setEnabled(false);
    ui->createFind->setEnabled(false);
    ui->deleteFind->setEnabled(false);
    ui->findBar->setLayout(hlayout2);
}
// 初始化TreeWidget组件
void MainWindow::treeWidgetInit()
{
    ui->treeWidget->clear();
    // 设置QTreeWidget的列数，这个决定了后面QStringList选取的个数
    ui->treeWidget->setColumnCount(1);
    // 设置QTreeWidget标题隐藏
    ui->treeWidget->setHeaderHidden(true);
    // 创建QTreeWidget的朋友节点 此时的父节点是TreeWidget
    QTreeWidgetItem *link = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("test")));
    link->setIcon(0,QIcon(":/img/sqlFish.png"));
    //Friend->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
    //Friend->setCheckState(0,Qt::Checked);

    std::vector<std::string> dblist;

    QDir directory("."); // 设置为当前目录
    QStringList filters;
    QStringList fileList = directory.entryList(QDir::Dirs);
    foreach (QString fileName, fileList) {
        if(fileName == "." || fileName == "..") continue;
        dblist.push_back(fileName.toStdString());
    }

    //循环添加子节点
    for(auto &db : dblist){
        QTreeWidgetItem *childDb = new QTreeWidgetItem(link);
        childDb->setIcon(0,QIcon(tr(":/img/sql2.png")));
        childDb->setText(0,QString::fromStdString(db));
        //设置双击切换数据库
        connect(ui->treeWidget,&QTreeWidget::itemDoubleClicked,[=](){
            if(childDb->isSelected()) {
                childDb->setIcon(0,QIcon(tr(":/img/sql1.png")));
                currentDb = childDb->text(0);
                qDebug()<< currentDb;
            }
        });
        //添加子选项
        QTreeWidgetItem *tableTree = new QTreeWidgetItem(QStringList(QString("表")));
        tableTree->setIcon(0,QIcon(tr(":/img/table.png")));
        QTreeWidgetItem *findTree = new QTreeWidgetItem(QStringList(QString("查询")));
        findTree->setIcon(0,QIcon(tr(":/img/sqlFind.png")));
        childDb->addChild(tableTree);
        childDb->addChild(findTree);

        //子选项被单击后，显示所有子内容，并且每次重新加载
        connect(ui->treeWidget,&QTreeWidget::itemClicked,[=](){
            if(tableTree->isSelected()){
                //加载上方工具栏
                ui->stackedWidget1->setCurrentIndex(0);
                //设置只有新建按钮启用
                ui->showTable->setEnabled(false);
                ui->alterTable->setEnabled(false);
                ui->createTable->setEnabled(true);
                ui->deleteTable->setEnabled(false);
                //qDebug()<< "tableTree->isSelected";
                ui->stackedWidget2->removeWidget(ui->stackedWidget2->currentWidget());
                QTableWidget* tableTreeWidget = new QTableWidget();
                tableTreeWidgetInit(tableTreeWidget);
                ui->stackedWidget2->addWidget(tableTreeWidget);
                ui->stackedWidget2->setCurrentWidget(tableTreeWidget);

                QList<QTreeWidgetItem *> children = tableTree->takeChildren();

                qDebug() << currentDb;
                if(!openDb) SmManager::open_db(currentDb.toStdString());
                std::vector<std::string> tablelist;
                SmManager::show_tables(tablelist);
                SmManager::close_db();
                openDb = false;
                for(auto &tb : tablelist){
                    qDebug()<< "tablelist";
                    //查询目录下所有的表文件
                    std::string path = "./" + currentDb.toStdString();
                    const char* pathChar = path.data();
                    if(chdir(pathChar) < 0){
                        throw UnixError();
                    }
                    // 设置当前工作目录，也可以是其他目录
                    QDir directory("./");
                    // 开始查找
                    QStringList files = directory.entryList(QStringList() << QString::fromStdString(tb), QDir::Files);
                    // 遍历找到的文件
                    foreach (QString file, files) {
                        QFileInfo fileInfo(file);
                        int row = tableTreeWidget->rowCount(); //获取当前行数
                        tableTreeWidget->insertRow(row);//插入新行
                        tableTreeWidget->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(tb)));
                        tableTreeWidget->setItem(row, 1, new QTableWidgetItem(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss")));
                        tableTreeWidget->setItem(row, 2, new QTableWidgetItem(QString::number(fileInfo.size()/1000) + "KB"));
                        tableTreeWidget->setItem(row, 3, new QTableWidgetItem("1"));
                        qDebug() << file << " size: " << fileInfo.size() << " bytes"
                                 << " modified: " << fileInfo.lastModified().toLocalTime();
                    }
                    if(chdir("..") < 0){
                        throw UnixError();
                    }

                    //每次都需要重新加载
                    qDebug() << "addChildren";
                    QTreeWidgetItem *childTable = new QTreeWidgetItem(QStringList(QString::fromStdString(tb)));
                    childTable->setIcon(0,QIcon(tr(":/img/table.png")));
                    tableTree->addChild(childTable);
                    //双击表自动打开表
                    connect(ui->treeWidget,&QTreeWidget::itemDoubleClicked,[=](){
                        if(childTable->isSelected()){
                            openTable(childTable->text(0));
                        }
                    });
                    //单击表可以激活其他按钮
                    connect(ui->treeWidget,&QTreeWidget::itemClicked,[=](){
                        if(childTable->isSelected()){
                            ui->showTable->setEnabled(true);
                            ui->deleteTable->setEnabled(true);
                            ui->alterTable->setEnabled(true);
                        }
                    });
                }
            }
            if(findTree->isSelected()){
                //加载上方工具栏
                ui->stackedWidget1->setCurrentIndex(1);
                //设置只有新建按钮启用
                ui->alterFind->setEnabled(false);
                ui->createFind->setEnabled(true);
                ui->deleteFind->setEnabled(false);
                qDebug("findTree->isSelected");
                ui->stackedWidget2->removeWidget(ui->stackedWidget2->currentWidget());
                QTableWidget* findTreeWidget = new QTableWidget();
                findTreeWidgetInit(findTreeWidget);
                ui->stackedWidget2->addWidget(findTreeWidget);
                ui->stackedWidget2->setCurrentWidget(findTreeWidget);

                findTree->takeChildren();

                //查询目录下所有的sql文件
                std::string path = "./" + currentDb.toStdString();
                const char* pathChar = path.data();
                if(chdir(pathChar) < 0){
                    throw UnixError();
                }
                QDir directory("./"); // 设置为当前目录
                QStringList filters;
                filters << "*.sql"; // 设置过滤器为*.sql文件
                QStringList fileList = directory.entryList(filters);
                foreach (QString fileName, fileList) {
                    qDebug() << "fileName:" << fileName;
                    QFileInfo fileInfo(fileName);
                    //qDebug() << "文件名: " << fileInfo.fileName();
                    //qDebug() << "修改时间: " << fileInfo.lastModified();
                    //qDebug() << "文件大小: " << fileInfo.size() << "字节";
                    int row = findTreeWidget->rowCount(); //获取当前行数
                    findTreeWidget->insertRow(row);//插入新行
                    findTreeWidget->setItem(row, 0, new QTableWidgetItem(fileInfo.fileName().replace(".sql","")));
                    findTreeWidget->setItem(row, 1, new QTableWidgetItem(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss")));
                    findTreeWidget->setItem(row, 2, new QTableWidgetItem(QString::number(fileInfo.size())+"KB"));
                    findTreeWidget->setItem(row, 3, new QTableWidgetItem("root"));

                    QTreeWidgetItem *childFind = new QTreeWidgetItem(QStringList(fileInfo.fileName()));
                    childFind->setIcon(0,QIcon(tr(":/img/sqlFind.png")));
                    findTree->addChild(childFind);
                    //点击后打开sql文件
                    connect(ui->treeWidget,&QTreeWidget::itemDoubleClicked,[=](){
                        if(childFind->isSelected()){
                            std::string path = "./" + currentDb.toStdString();
                            const char* pathChar = path.data();
                            if(chdir(pathChar) < 0){
                                throw UnixError();
                            }
                            QFile file(fileName);
                            openSql(file);
                            if(chdir("..") < 0){
                                throw UnixError();
                            }
                        }
                    });
                }
                if(chdir("..") < 0){
                    throw UnixError();
                }
            }
        });
        //frd1->setCheckState(0,Qt::Checked);
        //frd2->setCheckState(0,Qt::Unchecked);
    }
    //ui->treeWidget->addTopLevelItem(ClassMate);
    //ui->treeWidget->addTopLevelItem(Strange);
    // 展开QTreeWidget的所有节点
    //ui->treeWidget->expandAll();
    ui->treeWidget->resize(270,870);
    ui->treeWidget->setStyleSheet("QTreeWidget{border:none;}");
    ui->stackedWidget2->resize(1600,870);
}
//初始化tabwidget
void MainWindow::tabWidgetInit()
{
    ui->tabWidget->setMovable(true);
    ui->tabWidget->setTabsClosable(true);
    ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(ui->objectTab),QTabBar::RightSide,NULL);
    connect(ui->tabWidget->tabBar(), &QTabBar::tabCloseRequested, [=](int index){
        QWidget* widgetToRemove = ui->tabWidget->widget(index);
        if (widgetToRemove) {
            ui->tabWidget->removeTab(index);
            delete widgetToRemove;
        }
    });
    ui->tabWidget->setUsesScrollButtons(true);
    ui->tabWidget->setDocumentMode(true);//去边框
    ui->tabWidget->resize(1600,870);
}
//每个表格页面样式初始化
void MainWindow::tableWidgetInit(QTableWidget *tableWidget)
{
    //tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式
    tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止编辑
    //tableWidget->horizontalHeader()->setStretchLastSection(true); //行头自适应表格
    tableWidget->horizontalHeader()->setFont(QFont("song", 12));
    tableWidget->horizontalHeader()->setHighlightSections(false);//点击表时不对表头行光亮（获取焦点）
    tableWidget->verticalHeader()->setHidden(true);//去掉默认行号
    tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    tableWidget->setSortingEnabled(true);
    /*
    QString qs =    "QTableWidget::item:hover{background-color:#B9E3F4;color: white;}"
                 "QTableWidget::item:selected{background-color:#4D8CDA}"
                 "QHeaderView::section,QTableCornerButton:section{ \
        padding:3px; margin:0px; color:#242424;  border:1px ; \
        border-left-width:0px; border-right-width:1px; border-top-width:0px; border-bottom-width:1px; \
        background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #AB8CF5,stop:1 #CDBCF7); }"
    "QScrollBar:vertical {background-color: #9EC3EF;width: 10px;margin: 5px;padding: 2px;border: 1px solid #081832;border-radius: 5px;"
    "}";
tableWidget->setStyleSheet(qs);
*/
}
//展示查询的页面样式初始化
void MainWindow::findTreeWidgetInit(QTableWidget *tableWidget)
{
    tableWidget->setColumnCount(4);
    tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("名称"));
    tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("修改日期"));
    tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem("文件大小"));
    tableWidget->setHorizontalHeaderItem(3,new QTableWidgetItem("修改用户"));
    tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式
    //tableWidget->setSelectionMode(QAbstractItemView::MultiSelection);// 设置多行选取模式
    tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止编辑
    //tableWidget->horizontalHeader()->setStretchLastSection(true); //行头自适应表格
    tableWidget->horizontalHeader()->setFont(QFont("song", 12));
    tableWidget->horizontalHeader()->setHighlightSections(false);//点击表时不对表头行光亮（获取焦点）
    tableWidget->verticalHeader()->setHidden(true);//去掉默认行号
    tableWidget->setSortingEnabled(true);
    tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    for(int i = 0; i < 4; i++){
        tableWidget->setColumnWidth(i,100);
    }
    tableWidget->setStyleSheet("QTableWidget{border:none;}");
}
//初始化所有用户展示表格
void MainWindow::userWidgetInit(QTableWidget *tableWidget)
{
    tableWidget->setColumnCount(11);
    tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("用户名称"));
    tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("超级用户"));
    tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem("访问数据库权限"));
    tableWidget->setHorizontalHeaderItem(3,new QTableWidgetItem("创建数据库权限"));
    tableWidget->setHorizontalHeaderItem(4,new QTableWidgetItem("删除数据库权限"));
    tableWidget->setHorizontalHeaderItem(5,new QTableWidgetItem("查看表权限"));
    tableWidget->setHorizontalHeaderItem(6,new QTableWidgetItem("创建表权限"));
    tableWidget->setHorizontalHeaderItem(7,new QTableWidgetItem("修改表权限"));
    tableWidget->setHorizontalHeaderItem(8,new QTableWidgetItem("删除表权限"));
    tableWidget->setHorizontalHeaderItem(9,new QTableWidgetItem("创建索引权限"));
    tableWidget->setHorizontalHeaderItem(10,new QTableWidgetItem("删除索引权限"));
    //tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式
    //tableWidget->setSelectionMode(QAbstractItemView::MultiSelection);// 设置多行选取模式
    tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止编辑
    //tableWidget->horizontalHeader()->setStretchLastSection(true); //行头自适应表格
    tableWidget->horizontalHeader()->setFont(QFont("song", 12));
    tableWidget->horizontalHeader()->setHighlightSections(false);//点击表时不对表头行光亮（获取焦点）
    tableWidget->verticalHeader()->setHidden(true);//去掉默认行号
    tableWidget->setSortingEnabled(true);
    tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    for(int i = 0; i < 11; i++){
        tableWidget->setColumnWidth(i,200);
    }
    tableWidget->setStyleSheet("QTableWidget{border:none;}");
}

void MainWindow::createTableWidgetInit(QTableWidget *tableWidget)
{
    tableWidget->setColumnCount(3);
    tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("名称"));
    tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("类型"));
    tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem("长度"));
    //tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式
    //tableWidget->setSelectionMode(QAbstractItemView::MultiSelection);// 设置多行选取模式
    //tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止编辑
    //tableWidget->horizontalHeader()->setStretchLastSection(true); //行头自适应表格
    tableWidget->horizontalHeader()->setFont(QFont("song", 12));
    tableWidget->horizontalHeader()->setHighlightSections(false);//点击表时不对表头行光亮（获取焦点）
    tableWidget->verticalHeader()->setHidden(true);//去掉默认行号
    tableWidget->setSortingEnabled(true);
    tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    for(int i = 0; i < 3; i++){
        tableWidget->setColumnWidth(i,100);
    }
    tableWidget->setStyleSheet("QTableWidget{border:none;}");
}

void MainWindow::absWidgetInit(QTableWidget *tableWidget)
{
    tableWidget->setColumnCount(2);
    tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("查询"));
    tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("信息"));
    tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式
    //tableWidget->setSelectionMode(QAbstractItemView::MultiSelection);// 设置多行选取模式
    tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止编辑
    tableWidget->horizontalHeader()->setStretchLastSection(true); //行头自适应表格
    tableWidget->horizontalHeader()->setFont(QFont("song", 12));
    tableWidget->horizontalHeader()->setHighlightSections(false);//点击表时不对表头行光亮（获取焦点）
    tableWidget->verticalHeader()->setHidden(true);//去掉默认行号
    //tableWidget->setSortingEnabled(true);
    tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    tableWidget->setColumnWidth(0,1000);
    tableWidget->setStyleSheet("QTableWidget{border:none;}");
}

void MainWindow::dockWidgetInit()
{
    dockWidget = new QDockWidget(this);
    dockWidget->setAllowedAreas(Qt::BottomDockWidgetArea); // 设置允许从底部拉出
    dockWidget->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
    // 将组件添加到 QDockWidget 中
    showWidget = new QTabWidget();
    inforWidget = new QPlainTextEdit();
    inforWidget->setReadOnly(true);
    showWidget->addTab(inforWidget,"信息");

    absWidget = new QTableWidget();
    absWidgetInit(absWidget);
    showWidget->addTab(absWidget,"摘要");

    dockWidget->setWidget(showWidget);
    // 将 QDockWidget 添加到 QMainWindow
    this->addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
    dockWidget->setFeatures(QDockWidget::DockWidgetClosable);

    dockWidget->hide();
}
//展示表的页面样式初始化
void MainWindow::tableTreeWidgetInit(QTableWidget *tableWidget)
{
    //注意注意：！！！一定要设置列数或行数，否则不显示数据，tmd***，研究了半天，服了
    tableWidget->setColumnCount(4);
    tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("名称"));
    tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("修改日期"));
    tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem("数据大小"));
    tableWidget->setHorizontalHeaderItem(3,new QTableWidgetItem("行"));
    tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式
    //tableWidget->setSelectionMode(QAbstractItemView::MultiSelection);// 设置多行选取模式
    tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止编辑
    //tableWidget->horizontalHeader()->setStretchLastSection(true); //行头自适应表格
    tableWidget->horizontalHeader()->setFont(QFont("song", 12));
    tableWidget->horizontalHeader()->setHighlightSections(false);//点击表时不对表头行光亮（获取焦点）
    tableWidget->verticalHeader()->setHidden(true);//去掉默认行号
    tableWidget->setSortingEnabled(true);
    tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    for(int i = 0; i < 4; i++){
        tableWidget->setColumnWidth(i,150);
    }
    tableWidget->setStyleSheet("QTableWidget{border:none;}");
}
//关于界面
void MainWindow::on_actionAbout_triggered()
{
    AboutWidget* aboutWidget = new AboutWidget();
    aboutWidget->show();
}
//新建sql文件
void MainWindow::on_createFind_clicked()
{
    QWidget *editWidget = new QWidget();
    QWidget *butWidget = new QWidget();
    QPushButton *save = new QPushButton();
    save->setText("保存");
    save->setIcon(QIcon(":/img/Save.png"));
    save->setIconSize(QSize(20,20));
    save->setMinimumSize(90,40);
    save->setMaximumSize(90,40);
    QPushButton *run = new QPushButton();
    run->setText("运行");
    run->setIcon(QIcon(":/img/run.png"));
    run->setIconSize(QSize(20,20));
    run->setMinimumSize(90,40);
    run->setMaximumSize(90,40);
    // 创建水平布局
    QHBoxLayout *hlayout = new QHBoxLayout();
    //hlayout->setDirection(QBoxLayout::LeftToRight);
    hlayout->addWidget(save);
    hlayout->addWidget(run);
    hlayout->addStretch();//增加一个可伸缩空间

    butWidget->setLayout(hlayout);
    // 创建垂直布局
    QVBoxLayout *vlayout = new QVBoxLayout();
    vlayout->addWidget(butWidget);
    // 创建下部分的QPlainTextEdit
    CodeEditor *plainTextEdit = new CodeEditor();
    vlayout->addWidget(plainTextEdit);
    editWidget->setLayout(vlayout);

    //获取鼠标选中内容
    connect(plainTextEdit,&QPlainTextEdit::selectionChanged,[=](){
        if(!plainTextEdit->textCursor().selectedText().isEmpty()){
            run->setText("运行已选择的");
            run->setMinimumSize(150,40);
            run->setMaximumSize(150,40);
        }else{
            run->setText("运行");
            run->setMinimumSize(90,40);
            run->setMaximumSize(90,40);
        }
    });

    ui->tabWidget->addTab(editWidget,"无标题-查询");
    ui->tabWidget->setCurrentWidget(editWidget);

    connect(run,&QPushButton::clicked,[=](){
        if(!plainTextEdit->textCursor().selectedText().isEmpty()){
            // 遍历每一行，并删除#后面的注释内容
            QString sql = plainTextEdit->textCursor().selectedText().toUtf8();
            redBase(sql);
            //qDebug() << plainTextEdit->textCursor().selectedText();
        }else{
            QString sql = plainTextEdit->toPlainText().toUtf8();
            redBase(sql);
            //qDebug() << plainTextEdit->toPlainText();
        }
    });

    connect(save,&QPushButton::clicked,[=](){
        std::string path = "./" + currentDb.toStdString();
        const char* pathChar = path.data();
        if(chdir(pathChar) < 0){
            throw UnixError();
        }

        if(ui->tabWidget->tabText(ui->tabWidget->currentIndex()) == "无标题-查询"){
            bool ok;
            QString saveName = QInputDialog::getText(nullptr, "另存为", "请输入保存名称：", QLineEdit::Normal, "", &ok);
            // 创建文件对象
            if(ok && !saveName.isEmpty()){
                QFile file(saveName + ".sql");
                // 打开文件进行写入
                if (file.open(QIODevice::WriteOnly)) {
                    QTextStream out(&file);
                    // 将文本内容写入文件
                    out << plainTextEdit->toPlainText();
                    // 关闭文件
                    file.close();
                    QString text = QString::fromStdString(currentUser.getUsername())+"在"+ currentDb + "新建"+saveName+".sql查询文件";
                    qDebug() << text;
                    log.writeLog(text);
                } else {
                    qDebug() << "新建文件失败：" << file.errorString();
                }
            }
        }else{
            QFile file(ui->tabWidget->tabText(ui->tabWidget->currentIndex()) + ".sql");
            // 打开文件进行写入
            if (file.open(QIODevice::WriteOnly)) {
                QTextStream out(&file);
                // 将文本内容写入文件
                out << plainTextEdit->toPlainText();
                // 关闭文件
                file.close();
                QString text = QString::fromStdString(currentUser.getUsername())+"在"+ currentDb + "修改"+ui->tabWidget->tabText(ui->tabWidget->currentIndex())+".sql查询文件";
                qDebug() << text;
                log.writeLog(text);
            } else {
                qDebug() << "文件写入失败：" << file.errorString();
            } 
        }
        if(chdir("..") < 0){
            throw UnixError();
        }
    });
}
//打开sql文件
void MainWindow::openSql(QFile &file)
{
    QWidget *editWidget = new QWidget();
    QWidget *butWidget = new QWidget();
    QPushButton *save = new QPushButton();
    save->setText("保存");
    save->setIcon(QIcon(":/img/Save.png"));
    save->setIconSize(QSize(20,20));
    save->setMinimumSize(90,40);
    save->setMaximumSize(90,40);
    QPushButton *run = new QPushButton();
    run->setText("运行");
    run->setIcon(QIcon(":/img/run.png"));
    run->setIconSize(QSize(20,20));
    run->setMinimumSize(90,40);
    run->setMaximumSize(90,40);
    // 创建水平布局
    QHBoxLayout *hlayout = new QHBoxLayout();
    //hlayout->setDirection(QBoxLayout::LeftToRight);
    hlayout->addWidget(save);
    hlayout->addWidget(run);
    hlayout->addStretch();//增加一个可伸缩空间

    butWidget->setLayout(hlayout);
    // 创建垂直布局
    QVBoxLayout *vlayout = new QVBoxLayout();
    vlayout->addWidget(butWidget);
    // 创建下部分的QPlainTextEdit
    CodeEditor *plainTextEdit = new CodeEditor();
    if (file.open(QIODevice::ReadOnly)) {
        QTextStream in(&file);
        QString content = in.readAll();
        plainTextEdit->insertPlainText(content);
        //qDebug() << "文件内容：" << content;
    } else {
        qDebug() << "无法打开文件：" << file.fileName();
    }

    vlayout->addWidget(plainTextEdit);
    editWidget->setLayout(vlayout);

    //获取鼠标选中内容
    connect(plainTextEdit,&QPlainTextEdit::selectionChanged,[=](){
        if(!plainTextEdit->textCursor().selectedText().isEmpty()){
            run->setText("运行已选择的");
            run->setMinimumSize(150,40);
            run->setMaximumSize(150,40);
        }else{
            run->setText("运行");
            run->setMinimumSize(90,40);
            run->setMaximumSize(90,40);
        }
    });

    ui->tabWidget->addTab(editWidget,file.fileName().replace(".sql",""));
    ui->tabWidget->setCurrentWidget(editWidget);

    connect(run,&QPushButton::clicked,[=](){
        inforWidget->clear();
        absWidget->clearContents();
        absWidget->setRowCount(0);
        showWidget->removeTab(2);
        if(!plainTextEdit->textCursor().selectedText().isEmpty()){
            // 遍历每一行，并删除#后面的注释内容
            QString sql = plainTextEdit->textCursor().selectedText().toUtf8();
            redBase(sql);
            //qDebug() << plainTextEdit->textCursor().selectedText();
        }else{
            QString sql = plainTextEdit->toPlainText().toUtf8();
            redBase(sql);
            //qDebug() << plainTextEdit->toPlainText();
        }
    });

    connect(save,&QPushButton::clicked,[=](){
        std::string path = "./" + currentDb.toStdString();
        const char* pathChar = path.data();
        if(chdir(pathChar) < 0){
            throw UnixError();
        }
        QFile file(ui->tabWidget->tabText(ui->tabWidget->currentIndex()) + ".sql");
        // 打开文件进行写入
        if (file.open(QIODevice::WriteOnly)) {
            QTextStream out(&file);
            // 将文本内容写入文件
            out << plainTextEdit->toPlainText();
            // 关闭文件
            file.close();
            QString text = QString::fromStdString(currentUser.getUsername())+"在"+ currentDb + "新建"+ui->tabWidget->tabText(ui->tabWidget->currentIndex())+".sql查询文件";
            qDebug() << text;
            log.writeLog(text);
        } else {
            qDebug() << "文件写入失败：" << file.errorString();
        }
        if(chdir("..") < 0){
            throw UnixError();
        }
    });
}
//进行语法分析和解析
void MainWindow::redBase(QString &str)
{
    qDebug() << str;
    removeComments(str);
    qDebug() << str;
    QStringList list = str.replace("\n", "").split(";"); // 按照分号分割文本内容
    if(!openDb) SmManager::open_db(currentDb.toStdString());
    openDb = true;
    QString text = "";
    for(QString item : list) {
        if(item.isEmpty()) continue;
        item.append(";");
        qDebug() << item; // 输出分割后的文本内容
        text.append(QString::fromStdString(currentUser.getUsername())+"在"+ currentDb + "执行" + item + "\n");
        std::string line = item.toStdString();
        if (!line.empty()) {
            //首先捕捉语法问题
            try {
                YY_BUFFER_STATE buf = yy_scan_string(line.c_str());
                if (yyparse() == 0) {
                    if (ast::parse_tree != nullptr) {
                        try {
                            interp_sql(ast::parse_tree, QString::fromStdString(line));
                            qDebug() << "ok";
                        } catch (RedBaseError &e) {
                            //信息窗口
                            inforWidget->insertPlainText(item+"\n");
                            inforWidget->insertPlainText("> "+QString::fromStdString(e.what())+"\n");// 在标签中显示输出
                            //摘要窗口
                            int row = absWidget->rowCount();
                            absWidget->insertRow(row);
                            absWidget->setItem(row,0,new QTableWidgetItem(item));
                            absWidget->setItem(row,1,new QTableWidgetItem(QString::fromStdString(e.what())));
                            dockWidget->show();
                            std::cerr << e.what() << std::endl;
                            return;
                        }
                    }
                }
                yy_delete_buffer(buf);
            } catch (SQLError &e) {//处理sql语法问题
                //信息窗口
                inforWidget->insertPlainText(item+"\n");
                inforWidget->insertPlainText("> "+QString::fromStdString(e.what())+"\n");// 在标签中显示输出
                //摘要窗口
                int row = absWidget->rowCount();
                absWidget->insertRow(row);
                absWidget->setItem(row,0,new QTableWidgetItem(item));
                absWidget->setItem(row,1,new QTableWidgetItem(QString::fromStdString(e.what())));
                dockWidget->show();
                std::cerr << e.what();
                return;
            }
        }
    }
    SmManager::close_db();
    openDb = false;
    qDebug() << text;
    log.writeLog(text);
    resNum = 0;
}
//进行密码加密
QString MainWindow::pwdMD5(QString pwd)
{
    QByteArray array;
    array.append(pwd);
    QCryptographicHash hash(QCryptographicHash::Md5); //Md5加密
    hash.addData(array); //添加数据
    QByteArray retArray = hash.result(); //加密后的数据
    qDebug() << retArray.toHex(); //转化成16进制
    return retArray.toHex();
}

void MainWindow::removeComments(QString &text)
{
    QRegularExpression re("/\\*.*?\\*/"); // 匹配/**/之间的内容
    QString line = text.replace(re, ""); // 将匹配到的内容替换为空字符串
    QStringList lines = line.split("\n"); // 将文本分割成每一行
    text = "";
    for (const QString &line : lines) {
        QString modifiedLine = line.split("#").first().trimmed(); // 去除#及其后面的内容
        text.append(modifiedLine);
    }
}
//初始化用户
void MainWindow::userInit()
{
    try {
        if (!QDir("test").exists()) {
            QDir().mkdir("test");
        }
        if (chdir("./test") < 0) {
            throw UnixError();
        }
        std::string db_name = "sysUserDb";
        if (!SmManager::is_dir(db_name)) {
            // Database not found, create a new one
            SmManager::create_db(db_name);
            // Open database
            SmManager::open_db(db_name);
            QString pwd = pwdMD5("123456"); //"e10adc3949ba59abbe56e057f20f883e"
            //系统用户表和权限表，权限0表示没有，1表示有
            QStringList list = {"create table sysuser(id int,name char(32),password char(32),role int);",
                               "insert into sysuser values (0,'root','e10adc3949ba59abbe56e057f20f883e',1);",
                               "create table sysuserpermission(id int,ODB int,CDB int,DDB int,ST int,CT int,AT int,DT int,CI int,DI int);",
                               "insert into sysuserpermission values (0,1,1,1,1,1,1,1,1,1);"
                               };
            // 遍历分割后的文本列表
            for(QString item : list) {
                if(item.isEmpty()) continue;
                qDebug() << item; // 输出分割后的文本内容
                std::string line = item.toStdString();
                if (!line.empty()) {
                    YY_BUFFER_STATE buf = yy_scan_string(line.c_str());
                    if (yyparse() == 0) {
                        if (ast::parse_tree != nullptr) {
                            try {
                                Interp::interp_sql(ast::parse_tree);
                            } catch (RedBaseError &e) {
                                std::cerr << e.what() << std::endl;
                            }
                        }
                    }
                    yy_delete_buffer(buf);
                }
            }
            SmManager::close_db();
            //return;
        }
        SmManager::open_db(db_name);
        QString uline = "select * from sysuser;";
        std::vector<std::string> ucolumns;//每列数据
        //查询子表所有东西
        YY_BUFFER_STATE ubuf = yy_scan_string(uline.toStdString().c_str());
        if (yyparse() == 0) {
            if (ast::parse_tree != nullptr) {
                auto x = std::dynamic_pointer_cast<ast::SelectStmt>(ast::parse_tree);
                std::vector<Condition> conds = Interp::interp_where_clause(x->conds);
                std::vector<TabCol> sel_cols;
                for (auto &sv_sel_col : x->cols) {
                    TabCol sel_col(sv_sel_col->tab_name, sv_sel_col->col_name);
                    sel_cols.push_back(sel_col);
                }
                std::vector<std::string> captions;//标题
                size_t num_rec;
                QlManager::select_from(sel_cols, x->tabs, conds,captions,num_rec, ucolumns);
            }
        }
        yy_delete_buffer(ubuf);

        QString pline = "select * from sysuserpermission;";
        std::vector<std::string> pcolumns;//每列数据
        size_t num_rec = 0;
        //查询子表所有东西
        YY_BUFFER_STATE pbuf = yy_scan_string(pline.toStdString().c_str());
        if (yyparse() == 0) {
            if (ast::parse_tree != nullptr) {
                auto x = std::dynamic_pointer_cast<ast::SelectStmt>(ast::parse_tree);
                std::vector<Condition> conds = Interp::interp_where_clause(x->conds);
                std::vector<TabCol> sel_cols;
                for (auto &sv_sel_col : x->cols) {
                    TabCol sel_col(sv_sel_col->tab_name, sv_sel_col->col_name);
                    sel_cols.push_back(sel_col);
                }
                std::vector<std::string> captions;//标题
                QlManager::select_from(sel_cols, x->tabs, conds,captions,num_rec, pcolumns);
            }
        }
        yy_delete_buffer(pbuf);

        for(int i = 0; i < num_rec; i++){
            User user(ucolumns[1],std::stoi(ucolumns[3]));
            if(pcolumns[1] == "1"){
                superuser.assignPermission(user,Permission::OpenDatabase);
            }
            if(pcolumns[2] == "1"){
                superuser.assignPermission(user,Permission::CreateDatabase);
            }
            if(pcolumns[3] == "1"){
                superuser.assignPermission(user,Permission::DropDatabase);
            }
            if(pcolumns[4] == "1"){
                superuser.assignPermission(user,Permission::ShowTable);
            }
            if(pcolumns[5] == "1"){
                superuser.assignPermission(user,Permission::CreateTable);
            }
            if(pcolumns[6] == "1"){
                superuser.assignPermission(user,Permission::AlterTable);
            }
            if(pcolumns[7] == "1"){
                superuser.assignPermission(user,Permission::DropTable);
            }
            if(pcolumns[8] == "1"){
                superuser.assignPermission(user,Permission::CreateIndex);
            }
            if(pcolumns[9] == "1"){
                superuser.assignPermission(user,Permission::DropIndex);
            }
            userList.push_back(user);
        }
        SmManager::close_db();
    } catch (RedBaseError &e) {
        qDebug() << e.what();
        exit(1);
    }
}
//sql语法分析器
void MainWindow::interp_sql(const std::shared_ptr<ast::TreeNode> &root,QString cmd)
{
    if (auto x = std::dynamic_pointer_cast<ast::Help>(root)) {
        std::cout
            << "Supported SQL syntax:\n"
               "  command ;\n"
               "command:\n"
               "  CREATE TABLE table_name (column_name type [, column_name type ...])\n"
               "  DROP TABLE table_name\n"
               "  CREATE INDEX table_name (column_name)\n"
               "  DROP INDEX table_name (column_name)\n"
               "  INSERT INTO table_name VALUES (value [, value ...])\n"
               "  DELETE FROM table_name [WHERE where_clause]\n"
               "  UPDATE table_name SET column_name = value [, column_name = value ...] [WHERE where_clause]\n"
               "  SELECT selector FROM table_name [WHERE where_clause]\n"
               "type:\n"
               "  {INT | FLOAT | CHAR(n)}\n"
               "where_clause:\n"
               "  condition [AND condition ...]\n"
               "condition:\n"
               "  column op {column | value}\n"
               "column:\n"
               "  [table_name.]column_name\n"
               "op:\n"
               "  {= | <> | < | > | <= | >=}\n"
               "selector:\n"
               "  {* | column [, column ...]}\n";
    } else if (auto x = std::dynamic_pointer_cast<ast::ShowTables>(root)) {
        std::vector<std::string> tablelist;
        SmManager::show_tables(tablelist);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        //结果窗口
        if(!resNum) showWidget->removeTab(2);
        QTableWidget *resWidget = new QTableWidget();
        tableWidgetInit(resWidget);
        resWidget->setColumnCount(1);
        resWidget->setColumnWidth(0,200);
        resWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("Tables_in_"+currentDb));
        for(int i = 0; i < tablelist.size(); i++){
            int row = resWidget->rowCount();
            resWidget->insertRow(row);
            resWidget->setItem(row,0,new QTableWidgetItem(QString::fromStdString(tablelist[i])));
            qDebug() << QString::fromStdString(tablelist[i]);
        }
        showWidget->addTab(resWidget,"结果");
        showWidget->setCurrentWidget(resWidget);
        dockWidget->show();
        resNum++;
    } else if (auto x = std::dynamic_pointer_cast<ast::DescTable>(root)) {
        std::vector<std::string> captions;
        std::vector<std::string> all_field_info;
        SmManager::desc_table(x->tab_name,captions,all_field_info);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        //结果窗口
        if(!resNum) showWidget->removeTab(2);
        QTableWidget *resWidget = new QTableWidget();
        tableWidgetInit(resWidget);
        resWidget->setColumnCount(3);
        resWidget->setColumnWidth(0,200);
        resWidget->setColumnWidth(1,200);
        resWidget->setColumnWidth(2,200);
        QStringList headerLabels;
        for(auto &t : captions){
            headerLabels.append(QString::fromStdString(t));
            qDebug() << QString::fromStdString(t);
        }
        resWidget->setHorizontalHeaderLabels(headerLabels);
        for(int i = 0; i < all_field_info.size(); i+=3){
            int row = resWidget->rowCount();
            resWidget->insertRow(row);
            resWidget->setItem(row,0,new QTableWidgetItem(QString::fromStdString(all_field_info[i])));
            resWidget->setItem(row,1,new QTableWidgetItem(QString::fromStdString(all_field_info[i+1])));
            resWidget->setItem(row,2,new QTableWidgetItem(QString::fromStdString(all_field_info[i+2])));
            //qDebug() << QString::fromStdString(tablelist[i]);
        }
        showWidget->addTab(resWidget,"结果");
        showWidget->setCurrentWidget(resWidget);
        dockWidget->show();
        resNum++;
    } else if (auto x = std::dynamic_pointer_cast<ast::CreateTable>(root)) {
        std::vector<ColDef> col_defs;
        for (auto &field : x->fields) {
            if (auto sv_col_def = std::dynamic_pointer_cast<ast::ColDef>(field)) {
                ColDef col_def(sv_col_def->col_name, Interp::interp_sv_type(sv_col_def->type_len->type),
                               sv_col_def->type_len->len);
                col_defs.push_back(col_def);
            } else {
                throw InternalError("Unexpected field type");
            }
        }
        SmManager::create_table(x->tab_name, col_defs);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        showWidget->removeTab(2);
        dockWidget->show();
    } else if (auto x = std::dynamic_pointer_cast<ast::DropTable>(root)) {
        SmManager::drop_table(x->tab_name);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        showWidget->removeTab(2);
        dockWidget->show();
    } else if (auto x = std::dynamic_pointer_cast<ast::CreateIndex>(root)) {
        SmManager::create_index(x->tab_name, x->col_name);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        showWidget->removeTab(2);
        dockWidget->show();
    } else if (auto x = std::dynamic_pointer_cast<ast::DropIndex>(root)) {
        SmManager::drop_index(x->tab_name, x->col_name);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        showWidget->removeTab(2);
        dockWidget->show();
    } else if (auto x = std::dynamic_pointer_cast<ast::InsertStmt>(root)) {
        std::vector<Value> values;
        for (auto &sv_val : x->vals) {
            values.push_back(Interp::interp_sv_value(sv_val));
        }
        QlManager::insert_into(x->tab_name, values);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        showWidget->removeTab(2);
        dockWidget->show();
    } else if (auto x = std::dynamic_pointer_cast<ast::DeleteStmt>(root)) {
        std::vector<Condition> conds = Interp::interp_where_clause(x->conds);
        QlManager::delete_from(x->tab_name, conds);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        showWidget->removeTab(2);
        dockWidget->show();
    } else if (auto x = std::dynamic_pointer_cast<ast::UpdateStmt>(root)) {
        std::vector<Condition> conds = Interp::interp_where_clause(x->conds);
        std::vector<SetClause> set_clauses;
        for (auto &sv_set_clause : x->set_clauses) {
            SetClause set_clause(TabCol("", sv_set_clause->col_name), Interp::interp_sv_value(sv_set_clause->val));
            set_clauses.push_back(set_clause);
        }
        QlManager::update_set(x->tab_name, set_clauses, conds);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        showWidget->removeTab(2);
        dockWidget->show();
    } else if (auto x = std::dynamic_pointer_cast<ast::SelectStmt>(root)) {
        std::vector<Condition> conds = Interp::interp_where_clause(x->conds);
        std::vector<TabCol> sel_cols;
        for (auto &sv_sel_col : x->cols) {
            TabCol sel_col(sv_sel_col->tab_name, sv_sel_col->col_name);
            sel_cols.push_back(sel_col);
        }
        std::vector<std::string> captions;//标题
        size_t num_rec;
        std::vector<std::string> ucolumns;//每列数据
        QlManager::select_from(sel_cols, x->tabs, conds,captions,num_rec, ucolumns);
        //信息窗口
        inforWidget->insertPlainText(cmd+"\n"+"> OK\n");
        //摘要窗口
        int row = absWidget->rowCount();
        absWidget->insertRow(row);
        absWidget->setItem(row,0,new QTableWidgetItem(cmd));
        absWidget->setItem(row,1,new QTableWidgetItem("OK"));
        //结果窗口
        if(!resNum) showWidget->removeTab(2);
        QTableWidget *resWidget = new QTableWidget();
        tableWidgetInit(resWidget);
        QStringList headerLabels;
        for(auto &t : captions){
            headerLabels.append(QString::fromStdString(t));
            qDebug() << QString::fromStdString(t);
        }
        resWidget->setColumnCount(captions.size());
        resWidget->setHorizontalHeaderLabels(headerLabels);
        for(int i = 0; i < num_rec; i++){
            int row = resWidget->rowCount();
            resWidget->insertRow(row);
            for(int j = 0; j < captions.size(); j++){
                resWidget->setItem(row, j, new QTableWidgetItem(QString::fromStdString(ucolumns[j+i*captions.size()])));
                qDebug() << j << " " << QString::fromStdString(ucolumns[j+i*captions.size()]);
            }
        }
        showWidget->addTab(resWidget,"结果");
        showWidget->setCurrentWidget(resWidget);
        dockWidget->show();
        resNum++;
    } else {
        throw InternalError("Unexpected AST root");
    }
}
//用户界面展示
void MainWindow::on_actionUser_triggered()
{
    ui->stackedWidget2->removeWidget(ui->stackedWidget2->currentWidget());
    QTableWidget* userWidget = new QTableWidget();
    userWidgetInit(userWidget);
    ui->stackedWidget2->addWidget(userWidget);
    ui->stackedWidget2->setCurrentWidget(userWidget);
    for(auto u : userList){
        int row = userWidget->rowCount(); //获取当前行数
        userWidget->insertRow(row);//插入新行
        userWidget->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(u.getUsername())));
        if(u.getRole()==1){
            userWidget->setItem(row, 1, new QTableWidgetItem("是"));
        }else{
            userWidget->setItem(row, 1, new QTableWidgetItem("否"));
        }
        for(auto p : u.getPermissions()){
            if(p == Permission::OpenDatabase){
                userWidget->setItem(row, 2, new QTableWidgetItem("是"));
            }else if(p == Permission::CreateDatabase){
                userWidget->setItem(row, 3, new QTableWidgetItem("是"));
            }else if(p == Permission::DropDatabase){
                userWidget->setItem(row, 4, new QTableWidgetItem("是"));
            }else if(p == Permission::ShowTable){
                userWidget->setItem(row, 5, new QTableWidgetItem("是"));
            }else if(p == Permission::CreateTable){
                userWidget->setItem(row, 6, new QTableWidgetItem("是"));
            }else if(p == Permission::AlterTable){
                userWidget->setItem(row, 7, new QTableWidgetItem("是"));
            }else if(p == Permission::DropTable){
                userWidget->setItem(row, 8, new QTableWidgetItem("是"));
            }else if(p == Permission::CreateIndex){
                userWidget->setItem(row, 9, new QTableWidgetItem("是"));
            }else if(p == Permission::DropIndex){
                userWidget->setItem(row, 10, new QTableWidgetItem("是"));
            }
        }
    }

    QWidget *butWidget = new QWidget();
    QPushButton *editUser = new QPushButton();
    editUser->setText("编辑用户");
    editUser->setIcon(QIcon(":/img/pen.png"));
    editUser->setIconSize(QSize(20,20));
    editUser->setMinimumSize(120,40);
    editUser->setMaximumSize(120,40);
    QPushButton *crtUser = new QPushButton();
    crtUser->setText("新建用户");
    crtUser->setIcon(QIcon(":/img/add.png"));
    crtUser->setIconSize(QSize(20,20));
    crtUser->setMinimumSize(120,40);
    crtUser->setMaximumSize(120,40);
    QPushButton *deleteUser = new QPushButton();
    deleteUser->setText("删除用户");
    deleteUser->setIcon(QIcon(":/img/delete.png"));
    deleteUser->setIconSize(QSize(20,20));
    deleteUser->setMinimumSize(120,40);
    deleteUser->setMaximumSize(120,40);
    // 创建水平布局
    QHBoxLayout *hlayout = new QHBoxLayout();
    //hlayout->setDirection(QBoxLayout::LeftToRight);
    hlayout->addWidget(editUser);
    hlayout->addWidget(crtUser);
    hlayout->addWidget(deleteUser);
    hlayout->addStretch();//增加一个可伸缩空间
    hlayout->setContentsMargins(10, 10, 10, 10);//left,top,right,bottom

    butWidget->setLayout(hlayout);
    ui->stackedWidget1->addWidget(butWidget);
    ui->stackedWidget1->setCurrentWidget(butWidget);

    //设置保存按钮
    QPushButton *save = new QPushButton();
    save->setText("保存");
    save->setIcon(QIcon(":/img/Save.png"));
    save->setIconSize(QSize(20,20));
    save->setMinimumSize(90,40);
    save->setMaximumSize(90,40);
    hlayout->addWidget(save);
    save->hide();
    connect(save,&QPushButton::clicked,[=](){
        //写入数据到sysuser表
        userWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    });
    connect(editUser,&QPushButton::clicked,[=](){
        save->show();
        userWidget->setEditTriggers(QAbstractItemView::AllEditTriggers);
    });
    //设置插入user数据
    connect(crtUser,&QPushButton::clicked,[=](){
        createUserWidget();
    });
    //设置删除user数据
    connect(deleteUser,&QPushButton::clicked,[=](){
        save->show();
        int row = userWidget->currentRow(); //获取当前行数
        userWidget->removeRow(row);
    });
}
//创建表格界面
void MainWindow::on_createTable_clicked()
{
    createTable("无标题");
}
//新建数据库
void MainWindow::on_actionCDb_triggered()
{
    try {
        bool ok;
        QString saveName = QInputDialog::getText(nullptr, "新建数据库", "数据库名：", QLineEdit::Normal, "", &ok);
        // 创建文件对象
        if(ok && !saveName.isEmpty()){
            //SmManager::close_db();
            std::string db_name = saveName.toStdString();
            if (!SmManager::is_dir(db_name)) {
                // Database not found, create a new one
                SmManager::create_db(db_name);
                QTreeWidgetItem *childDb = new QTreeWidgetItem(ui->treeWidget->topLevelItem(0));
                childDb->setIcon(0,QIcon(tr(":/img/sql2.png")));
                childDb->setText(0,QString::fromStdString(db_name));
                QTreeWidgetItem *tableTree = new QTreeWidgetItem(QStringList(QString("表")));
                tableTree->setIcon(0,QIcon(tr(":/img/table.png")));
                QTreeWidgetItem *findTree = new QTreeWidgetItem(QStringList(QString("查询")));
                findTree->setIcon(0,QIcon(tr(":/img/sqlFind.png")));
                childDb->addChild(tableTree);
                childDb->addChild(findTree);

                connect(ui->treeWidget,&QTreeWidget::itemDoubleClicked,[=](){
                    if(childDb->isSelected()){
                        childDb->setIcon(0,QIcon(tr(":/img/sql1.png")));
                        currentDb = childDb->text(0);
                    }
                });

                //子选项被单击后，显示所有子内容，并且每次重新加载
                connect(ui->treeWidget,&QTreeWidget::itemClicked,[=](){
                    if(tableTree->isSelected()){
                        //加载上方工具栏
                        ui->stackedWidget1->setCurrentIndex(0);
                        //设置只有新建按钮启用
                        ui->showTable->setEnabled(false);
                        ui->alterTable->setEnabled(false);
                        ui->createTable->setEnabled(true);
                        ui->deleteTable->setEnabled(false);
                        //qDebug()<< "tableTree->isSelected";
                        ui->stackedWidget2->removeWidget(ui->stackedWidget2->currentWidget());
                        QTableWidget* tableTreeWidget = new QTableWidget();
                        tableTreeWidgetInit(tableTreeWidget);
                        ui->stackedWidget2->addWidget(tableTreeWidget);
                        ui->stackedWidget2->setCurrentWidget(tableTreeWidget);

                        QList<QTreeWidgetItem *> children = tableTree->takeChildren();

                        qDebug() << currentDb;
                        if(!openDb) SmManager::open_db(currentDb.toStdString());
                        std::vector<std::string> tablelist;
                        SmManager::show_tables(tablelist);
                        SmManager::close_db();
                        openDb = false;
                        for(auto &tb : tablelist){
                            qDebug()<< "tablelist";
                            //查询目录下所有的sql文件
                            std::string path = "./" + currentDb.toStdString();
                            const char* pathChar = path.data();
                            if(chdir(pathChar) < 0){
                                throw UnixError();
                            }
                            // 设置当前工作目录，也可以是其他目录
                            QDir directory("./");
                            // 开始查找
                            QStringList files = directory.entryList(QStringList() << QString::fromStdString(tb), QDir::Files);
                            // 遍历找到的文件
                            foreach (QString file, files) {
                                QFileInfo fileInfo(file);
                                int row = tableTreeWidget->rowCount(); //获取当前行数
                                tableTreeWidget->insertRow(row);//插入新行
                                tableTreeWidget->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(tb)));
                                tableTreeWidget->setItem(row, 1, new QTableWidgetItem(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss")));
                                tableTreeWidget->setItem(row, 2, new QTableWidgetItem(QString::number(fileInfo.size()/1000) + "KB"));
                                tableTreeWidget->setItem(row, 3, new QTableWidgetItem("1"));
                                qDebug() << file << " size: " << fileInfo.size() << " bytes"
                                         << " modified: " << fileInfo.lastModified().toLocalTime();
                            }
                            if(chdir("..") < 0){
                                throw UnixError();
                            }

                            //每次都需要重新加载
                            qDebug() << "addChildren";
                            QTreeWidgetItem *childTable = new QTreeWidgetItem(QStringList(QString::fromStdString(tb)));
                            childTable->setIcon(0,QIcon(tr(":/img/table.png")));
                            tableTree->addChild(childTable);
                            //双击表自动打开表
                            connect(ui->treeWidget,&QTreeWidget::itemDoubleClicked,[=](){
                                if(childTable->isSelected()){
                                    openTable(childTable->text(0));
                                }
                            });
                            //单击表可以激活其他按钮
                            connect(ui->treeWidget,&QTreeWidget::itemClicked,[=](){
                                if(childTable->isSelected()){
                                    ui->showTable->setEnabled(true);
                                    ui->deleteTable->setEnabled(true);
                                    ui->alterTable->setEnabled(true);
                                }
                            });
                        }
                    }
                    if(findTree->isSelected()){
                        //加载上方工具栏
                        ui->stackedWidget1->setCurrentIndex(1);
                        //设置只有新建按钮启用
                        ui->alterFind->setEnabled(false);
                        ui->createFind->setEnabled(true);
                        ui->deleteFind->setEnabled(false);
                        qDebug("findTree->isSelected");
                        ui->stackedWidget2->removeWidget(ui->stackedWidget2->currentWidget());
                        QTableWidget* findTreeWidget = new QTableWidget();
                        findTreeWidgetInit(findTreeWidget);
                        ui->stackedWidget2->addWidget(findTreeWidget);
                        ui->stackedWidget2->setCurrentWidget(findTreeWidget);

                        findTree->takeChildren();

                        //查询目录下所有的sql文件
                        std::string path = "./" + currentDb.toStdString();
                        const char* pathChar = path.data();
                        if(chdir(pathChar) < 0){
                            throw UnixError();
                        }
                        QDir directory("./"); // 设置为当前目录
                        QStringList filters;
                        filters << "*.sql"; // 设置过滤器为*.sql文件
                        QStringList fileList = directory.entryList(filters);
                        foreach (QString fileName, fileList) {
                            qDebug() << "fileName:" << fileName;
                            QFileInfo fileInfo(fileName);
                            //qDebug() << "文件名: " << fileInfo.fileName();
                            //qDebug() << "修改时间: " << fileInfo.lastModified();
                            //qDebug() << "文件大小: " << fileInfo.size() << "字节";
                            int row = findTreeWidget->rowCount(); //获取当前行数
                            findTreeWidget->insertRow(row);//插入新行
                            findTreeWidget->setItem(row, 0, new QTableWidgetItem(fileInfo.fileName().replace(".sql","")));
                            findTreeWidget->setItem(row, 1, new QTableWidgetItem(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss")));
                            findTreeWidget->setItem(row, 2, new QTableWidgetItem(QString::number(fileInfo.size())+"KB"));
                            findTreeWidget->setItem(row, 3, new QTableWidgetItem("root"));

                            QTreeWidgetItem *childFind = new QTreeWidgetItem(QStringList(fileInfo.fileName()));
                            childFind->setIcon(0,QIcon(tr(":/img/sqlFind.png")));
                            findTree->addChild(childFind);
                            //点击后打开sql文件
                            connect(ui->treeWidget,&QTreeWidget::itemDoubleClicked,[=](){
                                if(childFind->isSelected()){
                                    std::string path = "./" + currentDb.toStdString();
                                    const char* pathChar = path.data();
                                    if(chdir(pathChar) < 0){
                                        throw UnixError();
                                    }
                                    QFile file(fileName);
                                    openSql(file);
                                    if(chdir("..") < 0){
                                        throw UnixError();
                                    }
                                }
                            });
                        }
                        if(chdir("..") < 0){
                            throw UnixError();
                        }
                    }
                });

                QString text = QString::fromStdString(currentUser.getUsername())+"在"+ currentDb + "新建"+saveName+"数据库";
                qDebug() << text;
                log.writeLog(text);
            }
        }
    } catch (RedBaseError &e) {
        qDebug() << e.what();
        exit(1);
    }
}
//新建表或者修改表
void MainWindow::createTable(const QString &tabName)
{
    bool newTable = false;
    if(tabName == "无标题"){
        newTable = true;
    }
    QWidget *createTableWidget = new QWidget();
    QWidget *butWidget = new QWidget();
    QPushButton *save = new QPushButton();
    save->setText("保存");
    save->setIcon(QIcon(":/img/Save.png"));
    save->setIconSize(QSize(20,20));
    save->setMinimumSize(90,40);
    save->setMaximumSize(90,40);
    QPushButton *add = new QPushButton();
    add->setText("添加字段");
    add->setIcon(QIcon(":/img/add.png"));
    add->setIconSize(QSize(20,20));
    add->setMinimumSize(120,40);
    add->setMaximumSize(120,40);
    QPushButton *insert = new QPushButton();
    insert->setText("插入字段");
    insert->setIcon(QIcon(":/img/pen.png"));
    insert->setIconSize(QSize(20,20));
    insert->setMinimumSize(120,40);
    insert->setMaximumSize(120,40);
    QPushButton *del = new QPushButton();
    del->setText("删除字段");
    del->setIcon(QIcon(":/img/delete.png"));
    del->setIconSize(QSize(20,20));
    del->setMinimumSize(120,40);
    del->setMaximumSize(120,40);
    // 创建水平布局
    QHBoxLayout *hlayout = new QHBoxLayout();
    hlayout->addWidget(save);
    hlayout->addWidget(add);
    hlayout->addWidget(insert);
    hlayout->addWidget(del);
    hlayout->addStretch();//增加一个可伸缩空间
    hlayout->setContentsMargins(10, 5, 10, 5);//left,top,right,bottom

    butWidget->setLayout(hlayout);
    // 创建垂直布局
    QVBoxLayout *vlayout = new QVBoxLayout();
    vlayout->addWidget(butWidget);
    // 创建下部分的QTableWidget
    QTableWidget* tabWidget = new QTableWidget();
    createTableWidgetInit(tabWidget);
    vlayout->addWidget(tabWidget);
    vlayout->setContentsMargins(0,5,10,5);
    createTableWidget->setLayout(vlayout);
    //无标题说明是新建
    if(newTable){
        int row = tabWidget->rowCount(); //获取当前行数
        tabWidget->insertRow(row);//插入新行
        tabWidget->setItem(row,0,new QTableWidgetItem(""));
        QComboBox *typeBox = new QComboBox();
        typeBox->addItem("INT");
        typeBox->addItem("CHAR");
        typeBox->addItem("FLOAT");
        tabWidget->setCellWidget(row,1,typeBox);
        typeBox->setCurrentText("INT");
        tabWidget->setItem(row,2,new QTableWidgetItem(""));
    }else{//有标题说明是修改表
        try {
            QString line = "desc ";
            line.append(tabName + ";");
            qDebug() << line;
            if(!openDb) SmManager::open_db(currentDb.toStdString());
            //查询子表结构
            YY_BUFFER_STATE buf = yy_scan_string(line.toStdString().c_str());
            if (yyparse() == 0) {
                if (ast::parse_tree != nullptr) {
                    try {
                        auto x = std::dynamic_pointer_cast<ast::DescTable>(ast::parse_tree);
                        std::vector<std::string> captions;
                        std::vector<std::string> all_field_info;
                        SmManager::desc_table(x->tab_name,captions,all_field_info);

                        for(int i = 0; i < all_field_info.size(); i+=3){
                            int row = tabWidget->rowCount();
                            tabWidget->insertRow(row);
                            tabWidget->setItem(row,0,new QTableWidgetItem(QString::fromStdString(all_field_info[i])));
                            QComboBox *typeBox = new QComboBox();
                            typeBox->addItem("INT");
                            typeBox->addItem("CHAR");
                            typeBox->addItem("FLOAT");
                            tabWidget->setCellWidget(row,1,typeBox);
                            qDebug() << QString::fromStdString(all_field_info[i+1]);
                            if(QString::fromStdString(all_field_info[i+1]) == "INT"){
                                typeBox->setCurrentText("INT");
                            }else if(QString::fromStdString(all_field_info[i+1]) == "CHAR"){
                                typeBox->setCurrentText("CHAR");
                            }else if(QString::fromStdString(all_field_info[i+1]) == "FLOAT"){
                                typeBox->setCurrentText("FLOAT");
                            }
                            tabWidget->setItem(row,2,new QTableWidgetItem(""));
                        }
                    } catch (RedBaseError &e) {
                        std::cerr << e.what() << std::endl;
                    }
                }
            }
            yy_delete_buffer(buf);
            SmManager::close_db();
            openDb = false;
        } catch (SQLError &e) {//处理sql语法问题
            QMessageBox::critical(this, "",QString::fromStdString(e.what()));
            std::cerr << e.what();
        }
    }
    //输入东西后才能保存
    save->setEnabled(false);
    connect(tabWidget,&QTableWidget::itemClicked,[=](){
        save->setEnabled(true);
    });
    //执行保存
    connect(save,&QPushButton::clicked,[=](){
        //先看看有没有这个表，如果存在则删除
        if(!newTable){
            qDebug() << "存在表删除";
            dropTable(tabName);
        }
        QString cmd = "create table ";
        bool ok;
        QString saveName = "";
        if(newTable){
            saveName = QInputDialog::getText(nullptr, "另存为", "表名：", QLineEdit::Normal, "", &ok);
        }else{
            ok = true;
            saveName = tabName;
        }
        // 创建文件对象
        if(ok && !saveName.isEmpty()){
            cmd.append(saveName + "(");
            bool isChar = false;
            //调用创建表的sql语句
            for(int i = 0; i < tabWidget->rowCount(); i++){
                for(int j = 0; j < tabWidget->columnCount(); j++){
                    QString str;
                    if(j == 1){
                        str = dynamic_cast<QComboBox *>(tabWidget->cellWidget(i,j))->currentText();
                    }else{
                        str = tabWidget->item(i,j)->text();
                    }
                    qDebug() << str;
                    cmd.append(str + " ");
                    if(QString::compare(str,"INT") == 0 || QString::compare(str,"FLOAT") == 0){
                        break;
                    }
                    if(QString::compare(str,"CHAR") == 0){
                        isChar = true;
                        cmd.append("(");
                    }
                }
                if(isChar) cmd.append(")");
                cmd.append(",");
                isChar = false;
            }
            cmd.remove(cmd.length()-1,1);
            cmd.append(");");
            qDebug() << cmd;
            std::string line = cmd.toStdString();
            if (!line.empty()) {
                try {
                    if(!openDb) SmManager::open_db(currentDb.toStdString());
                    YY_BUFFER_STATE buf = yy_scan_string(line.c_str());
                    if (yyparse() == 0) {
                        if (ast::parse_tree != nullptr) {
                            try {
                                Interp::interp_sql(ast::parse_tree);
                                //qDebug() << "ok";
                            } catch (RedBaseError &e) {
                                std::cerr << e.what() << std::endl;
                            }
                        }
                    }
                    yy_delete_buffer(buf);
                    SmManager::close_db();
                    openDb = false;
                } catch (SQLError &e) {//处理sql语法问题
                    QMessageBox::critical(this, "",QString::fromStdString(e.what()));
                    std::cerr << e.what();
                }
            }
            if(newTable){
                QString text = QString::fromStdString(currentUser.getUsername())+"在"+ currentDb + "新建"+saveName+"表";
                qDebug() << text;
                log.writeLog(text);
            }else{
                QString text = QString::fromStdString(currentUser.getUsername())+"在"+ currentDb + "修改"+saveName+"表";
                qDebug() << text;
                log.writeLog(text);
            }
        }
    });
    //执行添加
    connect(add,&QPushButton::clicked,[=](){
        int row = tabWidget->rowCount(); //获取当前行数
        tabWidget->insertRow(row);//插入新行
        tabWidget->setItem(row,0,new QTableWidgetItem(""));
        QComboBox *typeBox = new QComboBox();
        typeBox->addItem("INT");
        typeBox->addItem("CHAR");
        typeBox->addItem("FLOAT");
        tabWidget->setCellWidget(row,1,typeBox);
        typeBox->setCurrentText("INT");
        tabWidget->setItem(row,2,new QTableWidgetItem(""));
    });
    //执行插入
    connect(insert,&QPushButton::clicked,[=](){
        int row = tabWidget->currentRow();
        tabWidget->insertRow(row);//插入新行
        tabWidget->setItem(row,0,new QTableWidgetItem(""));
        QComboBox *typeBox = new QComboBox();
        typeBox->addItem("INT");
        typeBox->addItem("CHAR");
        typeBox->addItem("FLOAT");
        tabWidget->setCellWidget(row,1,typeBox);
        typeBox->setCurrentText("INT");
        tabWidget->setItem(row,2,new QTableWidgetItem(""));
    });
    //执行删除
    connect(del,&QPushButton::clicked,[=](){
        int row = tabWidget->currentRow();
        tabWidget->removeRow(row);//插入新行
    });
    ui->tabWidget->addTab(createTableWidget,tabName+"-表");
    ui->tabWidget->setCurrentWidget(createTableWidget);
}
//打开表
void MainWindow::openTable(const QString &tabName)
{
    try {
        QString line = "select * from ";
        line.append(tabName + ";");
        qDebug() << line;
        //查询子表所有东西
        if(!openDb) SmManager::open_db(currentDb.toStdString());
        YY_BUFFER_STATE buf = yy_scan_string(line.toStdString().c_str());
        if (yyparse() == 0) {
            if (ast::parse_tree != nullptr) {
                try {
                    auto x = std::dynamic_pointer_cast<ast::SelectStmt>(ast::parse_tree);
                    std::vector<Condition> conds = Interp::interp_where_clause(x->conds);
                    std::vector<TabCol> sel_cols;
                    for (auto &sv_sel_col : x->cols) {
                        TabCol sel_col(sv_sel_col->tab_name, sv_sel_col->col_name);
                        sel_cols.push_back(sel_col);
                    }
                    std::vector<std::string> captions;//标题
                    size_t num_rec;
                    std::vector<std::string> ucolumns;//每列数据
                    QlManager::select_from(sel_cols, x->tabs, conds,captions,num_rec, ucolumns);

                    QTableWidget* tableWidget = new QTableWidget();// 两行三列
                    tableWidgetInit(tableWidget);
                    // 设置表头
                    QStringList headerLabels;
                    for(auto &t : captions){
                        headerLabels.append(QString::fromStdString(t));
                        qDebug() << QString::fromStdString(t);
                    }
                    tableWidget->setColumnCount(captions.size());
                    tableWidget->setHorizontalHeaderLabels(headerLabels);

                    for(int i = 0; i < num_rec; i++){
                        int row = tableWidget->rowCount(); //获取当前行数
                        tableWidget->insertRow(row);//插入新行
                        for(int j = 0; j < captions.size(); j++){
                            tableWidget->setItem(row, j, new QTableWidgetItem(QString::fromStdString(ucolumns[j+i*captions.size()])));
                            qDebug() << j << " " << QString::fromStdString(ucolumns[j+i*captions.size()]);
                        }
                    }

                    ui->tabWidget->addTab(tableWidget,tabName +"-表");
                } catch (RedBaseError &e) {
                    std::cerr << e.what() << std::endl;
                }
            }
        }
        yy_delete_buffer(buf);
        SmManager::close_db();
        openDb = false;
    } catch (SQLError &e) {//处理sql语法问题
        QMessageBox::critical(this, "",QString::fromStdString(e.what()));
        std::cerr << e.what();
    }
}

void MainWindow::on_showTable_clicked()
{
    openTable(ui->treeWidget->currentItem()->text(0));
}
//删除表
void MainWindow::dropTable(const QString &tabName)
{
    try {
        QString line = "drop table ";
        line.append(tabName + ";");
        qDebug() << line;
        if(!openDb) SmManager::open_db(currentDb.toStdString());
        //查询子表所有东西
        YY_BUFFER_STATE buf = yy_scan_string(line.toStdString().c_str());
        if (yyparse() == 0) {
            if (ast::parse_tree != nullptr) {
                try {
                    auto x = std::dynamic_pointer_cast<ast::DropTable>(ast::parse_tree);
                    SmManager::drop_table(x->tab_name);
                } catch (RedBaseError &e) {
                    std::cerr << e.what() << std::endl;
                }
            }
        }
        yy_delete_buffer(buf);
        SmManager::close_db();
        openDb = false;
        QString text = QString::fromStdString(currentUser.getUsername())+"在"+ currentDb + "删除"+tabName+"表";
        qDebug() << text;
        log.writeLog(text);
    } catch (SQLError &e) {//处理sql语法问题
        QMessageBox::critical(this, "",QString::fromStdString(e.what()));
        std::cerr << e.what();
    }
}
//创建用户
void MainWindow::createUserWidget()
{
    QWidget *createUserWidget = new QWidget();
    QWidget *butWidget = new QWidget();
    QPushButton *save = new QPushButton();
    save->setText("保存");
    save->setIcon(QIcon(":/img/Save.png"));
    save->setIconSize(QSize(20,20));
    save->setMinimumSize(90,40);
    save->setMaximumSize(90,40);
    // 创建水平布局
    QHBoxLayout *hlayout = new QHBoxLayout();
    hlayout->addWidget(save);
    hlayout->addStretch();//增加一个可伸缩空间
    hlayout->setContentsMargins(5, 5, 10, 5);//left,top,right,bottom

    butWidget->setLayout(hlayout);
    // 创建垂直布局
    QVBoxLayout *vlayout = new QVBoxLayout();
    vlayout->addWidget(butWidget);
    // 创建下部分的userWidget
    CreateUserWidget *userWidget = new CreateUserWidget();
    vlayout->addWidget(userWidget);
    vlayout->addStretch();
    createUserWidget->setLayout(vlayout);
    ui->tabWidget->addTab(createUserWidget,"无标题-用户");
    ui->tabWidget->setCurrentWidget(createUserWidget);

    connect(save,&QPushButton::clicked,[=](){
        //写入数据到sysuser表
        //todo
        User user("hp",1);
        createUser(user);
    });
}
//写入数据到sysuser表
void MainWindow::createUser(const User &user)
{
    //todo
}
//修改sysuser表
void MainWindow::changeUser(QTableWidget *userWidget)
{
    try {
        QString line = "drop table sysuser";
        qDebug() << line;
        if(!openDb) SmManager::open_db(currentDb.toStdString());
        //查询子表所有东西
        YY_BUFFER_STATE buf = yy_scan_string(line.toStdString().c_str());
        if (yyparse() == 0) {
            if (ast::parse_tree != nullptr) {
                try {
                    auto x = std::dynamic_pointer_cast<ast::DropTable>(ast::parse_tree);
                    SmManager::drop_table(x->tab_name);
                } catch (RedBaseError &e) {
                    std::cerr << e.what() << std::endl;
                }
            }
        }
        yy_delete_buffer(buf);
        SmManager::close_db();
        openDb = false;
    } catch (SQLError &e) {//处理sql语法问题
        QMessageBox::critical(this, "",QString::fromStdString(e.what()));
        std::cerr << e.what();
    }
}

void MainWindow::on_deleteTable_clicked()
{
    QMessageBox::StandardButton result = QMessageBox::warning(this,"","你确认要删除"+ui->treeWidget->currentItem()->text(0)+"表吗？");
    if(result == QMessageBox::Ok){
        dropTable(ui->treeWidget->currentItem()->text(0));
    }
}
//设计表
void MainWindow::on_alterTable_clicked()
{
    createTable(ui->treeWidget->currentItem()->text(0));
}

void MainWindow::on_actionSQl_triggered()
{
    QPlainTextEdit *help = new QPlainTextEdit();
    help->insertPlainText("Supported SQL syntax:\n"
                          "  command ;\n"
                          "command:\n"
                          "  CREATE TABLE table_name (column_name type [, column_name type ...])\n"
                          "  DROP TABLE table_name\n"
                          "  CREATE INDEX table_name (column_name)\n"
                          "  DROP INDEX table_name (column_name)\n"
                          "  INSERT INTO table_name VALUES (value [, value ...])\n"
                          "  DELETE FROM table_name [WHERE where_clause]\n"
                          "  UPDATE table_name SET column_name = value [, column_name = value ...] [WHERE where_clause]\n"
                          "  SELECT selector FROM table_name [WHERE where_clause]\n"
                          "type:\n"
                          "  {INT | FLOAT | CHAR(n)}\n"
                          "where_clause:\n"
                          "  condition [AND condition ...]\n"
                          "condition:\n"
                          "  column op {column | value}\n"
                          "column:\n"
                          "  [table_name.]column_name\n"
                          "op:\n"
                          "  {= | <> | < | > | <= | >=}\n"
                          "selector:\n"
                          "  {* | column [, column ...]}\n");
    help->setReadOnly(true);
    help->setFont(QFont("Arial Rounded MT Bold",16));
    help->setFixedSize(1413,520);
    help->show();
}

void MainWindow::on_actionFind_triggered()
{
    QPlainTextEdit *help = new QPlainTextEdit();
    help->insertPlainText("目前只有一个test连接，但是可以创建多个数据库，双击树形结构的"
                          "数据库即可切换为当前数据库；\n"
                          "显示表的行数目前为定值1，有时间再添加获取表行数的代码;\n"
                          "sql脚本文件可以点击运行，也可以选中多行运行；\n"
                          "sql文件虽然支持以#开头的注释，但是运行代码的时候不建议选中注释，\n"
                          "因为系统有时会把换行符识别成奇怪的东西，使得#后面的东西都被识别为注释，\n"
                          "目前不知道bug的成因，未来有时间再处理此问题；\n"
                          "新建用户和切换用户目前未完成，有时间再做；\n"
                          "int类型的数据赋值直接输入数字，\n"
                          "char类型的数据定义时需要输入长度，赋值时需要用单引号括起来，\n"
                          "float类型的数据定义时不需要输入长度，赋值时必须有小数点；\n"
                          "最后感谢大家的使用、支持和反馈，有问题请发邮件543261544@qq.com");
    help->setReadOnly(true);
    help->setFont(QFont("楷体",16));
    help->setFixedSize(1314,520);
    help->show();
}

void MainWindow::on_actionTable_triggered()
{
    createTable("无标题");
}
